package com.secsys.service.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;

import com.secsys.dao.HibernateBaseDAO;
import com.secsys.dao.impl.HibernateBaseDAOImpl;
import com.secsys.service.Service;

/**
 * @ClassName ServiceImpl
 * @Description 业务逻辑公共抽象类
 * @author LiusQ
 * @date 2011-3-28 4:17
 * @param <T>
 *            领域对象
 * @param <PK>
 *            主键类型
 */
public class ServiceImpl<T, PK extends Serializable> implements Service<T, PK> {
	protected static Map<String, String> descMap = new HashMap<String, String>();
	protected static Map<String, String> nameMap = new HashMap<String, String>();
	// 实体类由构造方法自动赋值
	private Class<T> entityObject;
	protected HibernateBaseDAO<T, PK> dao;
	Logger logger = Logger.getLogger(ServiceImpl.class);

	public void setSessionFactory(SessionFactory sessionFactory) {
		dao = new HibernateBaseDAOImpl<T, PK>(sessionFactory, entityObject);
	}

	/**
	 * @Description 构造方法，根据实例类自动获取实体类型
	 */
	@SuppressWarnings("unchecked")
	public ServiceImpl() {
		this.entityObject = null;
		Class<?> calzz = getClass();
		Type type = calzz.getGenericSuperclass();
		if (type instanceof ParameterizedType) {
			Type[] param = ((ParameterizedType) type).getActualTypeArguments();
			this.entityObject = (Class<T>) param[0];
			logger.info(entityObject.getSimpleName());
		}
	}

	@Override
	public void clear() {
		dao.clear();
	}

	@Override
	public Integer count() {
		return dao.count();
	}

	@Override
	public Integer count(String hql) {
		return dao.count(hql);
	}

	@Override
	public Integer count(String queryHql, Map<String, Date> map) {
		return dao.count(queryHql, map);
	}

	@Override
	public void delete(T entity) {
		dao.delete(entity);
	}

	@Override
	public void deleteAll(Collection<T> entities) {
		dao.deleteAll(entities);
	}

	@Override
	public void deleteById(PK id) {
		dao.deleteByKey(id);
	}

	@Override
	public List<T> findAllList() {
		List<T> list = dao.loadAll();
		return list;
	}

	@Override
	public List<T> findByHql(String hql) {
		return dao.find(hql);
	}
	
	@Override
	public List<T> find(String hql, Object[] values) {
		return dao.find(hql, values);
	}
	
	@Override
	public List<T> findByProperty(String hql, Object value) {
		return dao.findByProperty(hql, value);
	}

	@Override
	public List<T> findByHql(String hql, int offset, int size) {
		return dao.findBySql(hql, offset, size);
	}

	@Override
	public List<T> findByHql(String hql, int offset, int size,
			Map<String, Date> map) {
		return dao.findBySql(hql, offset, size, map);
	}

	@Override
	public T findById(PK id) {
		T entity = dao.get(id);
		return entity;
	}

	@Override
	public void flush() {
		dao.flush();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<?> getObject(Class clazz) {
		return dao.loadAll(clazz);
	}

	/**
	 * @Description 截取记录
	 * @param objectList
	 * @param startPage
	 * @param pageSize
	 *            return list
	 */
	public List<T> subListPage(List<T> objectList, int startPage, int pageSize) {
		return ((List<T>) objectList).subList(startPage <= 0 ? 0 : startPage,
				startPage + pageSize > objectList.size() ? objectList.size()
						: startPage + pageSize);
	}

	/**
	 * @Description 分页检索
	 * @param startSize
	 * @param pageSize
	 * @return list
	 */
	@SuppressWarnings("null")
	public List<T> listPage(int startSize, int pageSize) {
		List<T> objectList = findAllList();
		if (objectList == null && objectList.size() < pageSize + 1)
			return null;
		return subListPage(objectList, startSize, pageSize);
	}

	@Override
	public T load(PK id) {
		return dao.load(id);
	}

	public void save(T entity) {
		dao.save(entity);
	}

	@Override
	public Object saveObjectReturn(Object obj) {
		dao.saveObjectReturn(obj);
		return obj;
	}

	@Override
	public void saveOrUpdate(T entity) {
		dao.saveOrUpdate(entity);
		
	}
   
}
